#pragma region  【算法5 - 8】建立无向图的深度优先生成森林的孩子兄弟链表 
int flag[N] = {0}; //全局访问标志数组，初始化为0
void DFSForest(Graph *G, CSTree *T)
{
    //建立无向图G的深度优先生成森林T，森林用孩子兄弟链表存储,N是图顶点个数
    CSNode *p, *q; // CSNode是孩子兄弟存储方法的结点类型
    *T = NULL;
    for (v = 0; v < N; v++)
        if (!flag[v]) //顶点v为新的生成树的根结点
        {
            p = (CSNode *)malloc(sizeof(CSNode)); //分配根结点
            p = {GetVex(G, v), NULL, NULL};       //给根结点赋值
            if (!(*T))
                *T = p; // T是第一棵生成树的根
            else
                q->nextsibling = p; //前一棵的根的兄弟是其它生成树的根
            q = p;                  // q指示当前生成树的根
            DFSTree(G, v, &p);      //建立以p为根的生成树
        }
}
void DFSTree(Graph *G, int v, CSTree *T)
{ //从第v个顶点出发深度优先遍历图G，建立以*T为根的生成树
    // Graph是图G的形式存储类型，CSTree是指向CSNode的指针类型
    CSNode *p, *q, *w;
    int first; // first用于标记是否访问了第一个孩子
    flag[v] = 1;
    first = 1;
    for (w = FirstAdjVex(G, v); w; w = NextAdjVex(G, v, w))
        if (!flag[w])
        {
            p = (CSNode *)malloc(sizeof(CSNode)); //分配孩子结点
            *p = {GetVex(G, w), NULL, NULL};
            if (first) // w是v的第一个未被访问的邻接顶点，作为根的左孩子结点
            {
                (*T)->lchild = p;
                first = 0;
            }
            else
                q->nextsibling = p; // w是v的其它未被访问的邻接顶点，作为上一邻接点的右兄弟
            q = p;
            DFSTree(G, w, &q); //从第w个顶点出发深度优先遍历图G，建立生成子树*q
        }
}
#pragma endregion